<?php
require_once 'system/globals.php';
require_once 'system/phpQuery.php';
require_once 'service.php';

class Parser
{

    protected $link;
    protected $cache;
    protected $profiling;
    protected $profilingLog = array();
    protected $cached = array();
    protected $masks = array();
    protected $module;
    protected $tracklist = null;
    protected $id = null;
    protected $lastExecTime = 0;
    protected $totalExecTime = 0;

    function __construct($link, $cache = true, $profiling = true) {
        $this->cache = (bool)$cache;
        $this->profiling = (bool)$profiling;
        $this->link = $link;
        $this->modulesInfo = registerModules('modules');
        foreach($this->modulesInfo as $module) {
            if(preg_match('/' . $module['mask'] . '/i', $link) == true) {
                list($this->module, $this->id) = array($module['fileName'], $module['id']);
                break;
            }
        }
        if(! is_null($this->id)) {
            
            require_once $this->module;
            $m = 'Service_' . $this->id;
            $this->obj = new $m($link);
        } else {
            throw new Exception('Link ' . $link . ' can\'t be parsed');
        }
    }
    
    function getObject() {
        return $this->obj;
    }
    
    function __invoke() {
        return $this->getObject();
    }

    
    function track($number) {
        if ($this->tracklist == null) {
            $this->tracklist = $this->get('tracklist');
        }
        if (isset($this->tracklist[$number])) {
            return new ArrayObject($this->tracklist[$number], ArrayObject::ARRAY_AS_PROPS);
        }
        return false;
    }
    
    function tracks() {
        if ($this->tracklist == null) {
            $this->tracklist = $this->get('tracklist');
        }
        return $this->tracklist;
    }
    
    function get($key) {
    
        if($this->cache && isset($this->cached[$key])) {
            $this->profilingLog[] = 'Элемент "' . $key . '" был достан из кэша';
            return $this->cached[$key];
        }
    
        if (method_exists($this->obj, 'get' . ucfirst($key)) == true) {
            $tStart = microtime(true);
            $returnValue = call_user_func(array($this->obj, 'get' . ucfirst($key)));
            $tEnd = microtime(true);
            $this->lastExecTime = $tEnd - $tStart;
            $this->totalExecTime += $tEnd - $tStart;
            
            if($this->profiling) {
                $this->profilingLog[] = 'Был вызан метод "get' . ucfirst($key) . '", время парсинга: ' . round($this->lastExecTime, 3) . ' секунд';
            }
            
            if($this->cache) {
                $this->cached[$key] = $returnValue;
            }
            return $returnValue;
        }
        return false;
    }
    
    
    function __get($key) {
        return $this->get($key);
    }
    
    public function __isset($key) {
        return method_exists($this->obj, 'get' . ucfirst($key));
    }
    
    public function __toString() {
        return $this->link;
    }
    
    public function lastExecTime() {
        return $this->lastExecTime;
    }
    
    public function totalExecTime() {
        return $this->totalExecTime;
    }
    
    public function profilingLog() {
        return $this->profilingLog;
    }

}